package com.ruoyi.asset.service.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.ruoyi.asset.domain.*;
import com.ruoyi.asset.mapper.*;
import com.ruoyi.asset.service.IAssetFlowTypeService;
import com.ruoyi.asset.service.IAssetInfoService;
import com.ruoyi.base.domain.BaseCategory;
import com.ruoyi.base.service.IBaseCategoryService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.asset.service.IAssetInOutService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 出入库记录Service业务层处理
 * 
 * @author yepanpan
 * @date 2024-12-24
 */
@Service
public class AssetInOutServiceImpl implements IAssetInOutService 
{
    @Autowired
    private AssetInOutMapper assetInOutMapper;
    @Autowired
    private IAssetInfoService assetInfoService;
    @Autowired
    private AssetFlowMapper assetFlowMapper;
    @Autowired
    private IAssetFlowTypeService assetFlowTypeService;
    @Autowired
    private IBaseCategoryService baseCategoryService;
    @Autowired
    private AssetMaintainMapper assetMaintainMapper;
    @Autowired
    private ISysConfigService configService;

    /**
     * 查询出入库记录
     * 
     * @param id 出入库记录主键
     * @return 出入库记录
     */
    @Override
    public AssetInOut selectAssetInOutById(Long id)
    {
        return assetInOutMapper.selectAssetInOutById(id);
    }

    /**
     * 查询出入库记录列表
     * 
     * @param assetInOut 出入库记录
     * @return 出入库记录
     */
    @Override
    public List<AssetInOut> selectAssetInOutList(AssetInOut assetInOut)
    {
        return assetInOutMapper.selectAssetInOutList(assetInOut);
    }

    /**
     * 新增出入库记录
     * 
     * @param assetInOut 出入库记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertAssetInOut(AssetInOut assetInOut)
    {
        AssetFlow assetFlow = assetFlowMapper.selectAssetFlowById(assetInOut.getFlowId());

        if(assetFlow.getFlowStatus().equalsIgnoreCase(AssetFlow.STATUS_DONE)
                || assetFlow.getFlowStatus().equalsIgnoreCase(AssetFlow.STATUS_SCRAP)){
            throw new ServiceException("工单已经结束或者停止，不能进行出入库操作");
        }

        if(assetInOut.getAssetId() == null){
            assetInOut.setAssetId(assetFlow.getAssetId());
            assetInOut.setAssetNum(assetFlow.getAssetNum());
        }
        AssetFlowType assetFlowType = assetFlowTypeService.selectAssetFlowTypeById(assetFlow.getTypeId());
        assetFlow.setType(assetFlowType);

        if(assetInOut.getType().equalsIgnoreCase(AssetInOut.TYPE_IN)){
            if(assetFlowType.getCode().equalsIgnoreCase(AssetFlow.TYPE_PURCHASE)){
                purchaseAsset(assetInOut, assetFlow);
            }else{
                revertAsset(assetInOut, assetFlow);
            }
        }else if(assetInOut.getType().equalsIgnoreCase(AssetInOut.TYPE_OUT)){
            outAsset(assetInOut, assetFlow);
        } else{
            throw new ServiceException("不支持的操作类型");
        }

        assetInOut.setIoTime(new Date());
        assetInOut.setUserId(SecurityUtils.getUserId());
        return assetInOutMapper.insertAssetInOut(assetInOut);
    }

    /**
     * 出库
     * @param assetInOut
     * @return
     */
    public void outAsset(AssetInOut assetInOut, AssetFlow assetFlow){
        if(assetFlow.getType().getCode().equalsIgnoreCase(AssetFlow.TYPE_PURCHASE)){
            throw new ServiceException("采购工单，不能进行出库操作");
        }

        //其它工单需要找到对应的出库进行操作
        AssetInfo assetInfo = assetInfoService.selectAssetInfoById(assetInOut.getAssetId());

        if(assetInfo == null){
            throw new ServiceException("未找到资产信息");
        }

        //再更新工单为完成状态
        if(assetFlow.getType().getNeedRevert().equalsIgnoreCase("N")){
            //不需要归还
            assetFlow.setFlowStatus(AssetFlow.STATUS_DONE);
        }else{
            assetFlow.setFlowStatus(AssetFlow.STATUS_OUT);
            //更新资产为在用
            assetInfo.setIsUse("Y");
            assetInfo.setUserId(assetFlow.getUserId());
        }

        if(StringUtils.isEmpty(assetFlow.getType().getAssetStatus())){
            assetInfo.setStatus(assetFlow.getType().getAssetStatus());
        }

        assetInfo.setInStore("N");
        assetInfoService.updateAssetInfo(assetInfo);
        assetFlowMapper.updateAssetFlow(assetFlow);

    }

    /**
     * 归还入库
     * @param assetInOut
     * @return
     */
    public void revertAsset(AssetInOut assetInOut, AssetFlow assetFlow){
        if(assetFlow.getType().getCode().equalsIgnoreCase(AssetFlow.TYPE_PURCHASE)){
            throw new ServiceException("采购工单，不能进行归还操作");
        }
        if(assetFlow.getType().getNeedRevert().equalsIgnoreCase("N")){
            throw new ServiceException(assetFlow.getTypeName()+"工单不需要归还");
        }

        if(!assetFlow.getFlowStatus().equalsIgnoreCase(AssetFlow.STATUS_OUT)){
            throw new ServiceException("未出库的工单，不能进行归还操作");
        }

        //其它工单需要找到对应的出库进行操作
        AssetInfo assetInfo = assetInfoService.selectAssetInfoById(assetInOut.getAssetId());

        if(assetInfo == null){
            throw new ServiceException("未找到资产信息");
        }

        //先更新资产状态
        assetInfo.setHouseId(assetInOut.getHouseId());
        assetInfo.setInStore("Y");
        assetInfo.setIsUse("N");
        assetInfo.setUserId(null);

        //更新维修状态
        if(assetFlow.getType().getCode().equalsIgnoreCase(AssetFlow.TYPE_MAINTAIN)){
            AssetMaintain assetMaintain = assetMaintainMapper.selectAssetMaintainByFlowId(assetFlow.getId());
            if(assetMaintain != null && assetMaintain.getResult().equalsIgnoreCase(AssetMaintain.RESULT_FAIL)){
                assetInfo.setStatus(AssetInfo.STATUS_FAULT);
            }
        }
        assetInfoService.updateAssetInfo(assetInfo);

        //再更新工单为完成状态
        assetFlow.setFlowStatus(AssetFlow.STATUS_DONE);
        assetFlowMapper.updateAssetFlow(assetFlow);

    }

    /**
     * 采购入库
     * @param assetInOut
     * @param assetFlow
     */
    public void purchaseAsset(AssetInOut assetInOut, AssetFlow assetFlow){
        //先确认工单
        if(!assetFlow.getType().getCode().equalsIgnoreCase(AssetFlow.TYPE_PURCHASE)){
            throw new ServiceException("非采购入库，必须选择出库资产");
        }
        if(!assetFlow.getCheckStatus().equalsIgnoreCase(FlowCheck.CHECK_AGREE)){
            throw new ServiceException("工单未审核通过，不能入库");
        }

        AssetInOut ioc = new AssetInOut();
        ioc.setFlowId(assetInOut.getFlowId());
        List<AssetInOut> olds = assetInOutMapper.selectAssetInOutList(ioc);
        if(olds.size() >= assetFlow.getAmount()){
            assetFlow.setFlowStatus(AssetFlow.STATUS_DONE);
            assetFlowMapper.updateAssetFlow(assetFlow);

            throw new ServiceException("入库数量不能大于采购数量");
        }

        String nums;
        if(StringUtils.isNotEmpty(assetInOut.getAssetNum())){
            //不自动编码
            AssetInfo assetInfo = assetInfoService.selectAssetInfoByNum(assetInOut.getAssetNum());
            if(assetInfo != null){
                throw new ServiceException("资产 "+assetInOut.getAssetNum()+" 已存在，不能重复入库");
            }
            nums = assetInOut.getAssetNum();
        }else{
            //自动编码
            BaseCategory baseCategory = baseCategoryService.selectBaseCategoryById(assetFlow.getCateId());
            nums = baseCategory.getNums();
            if(StringUtils.isEmpty(nums)){
                nums = configService.selectConfigByKey("asset.num");
                if(StringUtils.isEmpty(nums)){
                    nums = "ZC-年-月-序号";
                }else{
                    nums = nums.trim();
                }
            }
            Calendar calendar = Calendar.getInstance();
            nums = nums.replaceAll("年", calendar.get(Calendar.YEAR)+"");
            nums = nums.replaceAll("月", (calendar.get(Calendar.MONTH)+1)+"");

            String pre= nums.replaceAll("序号","");
            String mm = assetInfoService.selectMaxAssetInfoNum(pre);
            if(mm == null){
                nums = pre+String.format("%03d", 1);
            }else{
                String n = mm.substring(pre.length());
                nums = pre+String.format("%03d", Integer.parseInt(n)+1);
            }
        }

        //先保存资产信息
        AssetInfo assetInfo = new AssetInfo();
        assetInfo.setBuyTime(new Date());
        assetInfo.setCateId(assetFlow.getCateId());
        assetInfo.setNum(nums);
        assetInfo.setHouseId(assetInOut.getHouseId());
        assetInfo.setStatus(AssetInfo.STATUS_NORMAL);
        assetInfo.setInStore("Y");
        assetInfo.setIsUse("N");
        assetInfo.setUserId(null);
        assetInfo.setDeptId(null);
        assetInfo.setPrice(assetFlow.getPrice());
        assetInfoService.insertAssetInfo(assetInfo);

        //判断采购是否已经结束
        if(olds.size() +1 >= assetFlow.getAmount()){
            assetFlow.setFlowStatus(AssetFlow.STATUS_DONE);
            assetFlowMapper.updateAssetFlow(assetFlow);
        }

        //再保存入库信息
        assetInOut.setAssetNum(assetInfo.getNum());
        assetInOut.setAssetId(assetInfo.getId());
    }

    /**
     * 修改出入库记录
     * 
     * @param assetInOut 出入库记录
     * @return 结果
     */
    @Override
    public int updateAssetInOut(AssetInOut assetInOut)
    {
        return assetInOutMapper.updateAssetInOut(assetInOut);
    }

    /**
     * 批量删除出入库记录
     * 
     * @param ids 需要删除的出入库记录主键
     * @return 结果
     */
    @Override
    public int deleteAssetInOutByIds(Long[] ids)
    {
        return assetInOutMapper.deleteAssetInOutByIds(ids);
    }

    /**
     * 删除出入库记录信息
     * 
     * @param id 出入库记录主键
     * @return 结果
     */
    @Override
    public int deleteAssetInOutById(Long id)
    {
        return assetInOutMapper.deleteAssetInOutById(id);
    }
}
